<?php
// +----------------------------------------------------------------------
// | INPHP
// | Copyright (c) 2023 https://inphp.cc All rights reserved.
// | Licensed ( https://opensource.org/licenses/MIT )
// | Author: 幺月儿(https://gitee.com/lulanyin) Email: inphp@qq.com
// +----------------------------------------------------------------------
// | 授权注解，自动使用SSO账户(前提是已安装该模块)
// +----------------------------------------------------------------------
namespace app\admin\attributes;

use Inphp\Core\Db\Redis;
use Inphp\Core\Modules;
use Inphp\Core\Services\Http\Cookie;
use Inphp\Core\Services\Http\Session;

#[\Attribute(\Attribute::TARGET_ALL)] class auth
{
    /**
     * 是否需要管理员权限
     * @var bool
     */
    private bool $admin = false;

    /**
     * 权限需求
     * @var string|array|null
     */
    private string|array|null $permission = null;

    /**
     * 用户信息存放属性
     * @var string
     */
    private string $user = "user";

    /**
     *
     * @param string|array|null $permission 权限参数
     * @param bool $admin 是否需要管理员权限
     */
    public function __construct(string|array|null $permission = null, bool $admin = false)
    {
        $this->admin = $admin;
        $this->permission = $permission;
    }

    /**
     * 处理权限
     * @param ...$args
     */
    public function process(...$args)
    {
        //统一方法获取
        $user = authUserInfo();
        if (is_null($user)) {
            httpResponse(httpMessage(30))->end();
            return;
        }
        $uid = $user["uid"];
        $token = $user["token"];
        if ($uid < 0) {
            //查询超管配置
            $config = Modules::getModule("admin")->getConfig("auth");
            $config = is_array($config) ? $config : [];
            //延长Token
            //保存到缓存， 超级管理员，默认有效时长为1小时
            $adminLifeTime = $config["lifeTime"] ?? 3600;
            $adminLifeTime = is_numeric($adminLifeTime) && $adminLifeTime >= 3600 ? $adminLifeTime : 3600;
            $adminLifeTime = min($adminLifeTime, 86400);
            Redis::set("Token_{$token}", $uid, $adminLifeTime);
            Session::set("token", $token);
        } elseif ($sso = Modules::getModule("sso")) {
            //超管
            if ($this->admin && $user["admin"] != 1) {
                httpResponse(httpMessage(31))->end();
                return;
            }
            //非管理员，且带有权限需求
            if (!empty($this->permission) && $user["admin"] != 1) {
                //权限判断
                $permission = is_array($this->permission) ? $this->permission : explode(",", $this->permission);
                //
                if (!\app\sso\model\UserModel::matchPermissionByGroups($permission, $user["groups"])) {
                    httpResponse(httpMessage(31))->end();
                    return;
                }
            }
        } else {
            httpResponse(httpMessage(30))->end();
            return;
        }
        list($type, $controller, $target) = $args;
        if (is_object($controller)) {
            if (property_exists($controller, $this->user)) {
                $controller->{$this->user} = $user;
            }
            if (property_exists($controller, "uid")) {
                $controller->uid = $uid > 0 ? $uid : 0;
            }
            if (property_exists($controller, "token")) {
                $controller->token = $token;
            }
        }
    }
}